/********************************************************************************
 * @file    app_nvs.c
 * @brief   nvs应用逻辑处理
 * 
 * @author  nzttj
 * @date    2025-02-14
 * @version 1.0
 * 
 * Copyright (C) 2025 nzttj
 * 
 * 本软件使用 GNU 通用公共许可证 (GPL) 第 3 版授权。
 * 
 * 您可以自由使用、修改、分发本软件，但必须遵守以下条件：
 * 1. 源代码必须开放，且您修改后的代码也必须以 GPL 许可证发布。
 * 2. 发布或分发本软件时，必须附带本许可证，并提供源代码或获取源代码的方式。
 * 
 * 本软件按“原样”提供，不附带任何担保，使用风险由用户自行承担。
 * 
 ********************************************************************************/

#include "app_nvs.h"
#include "hal_nvs.h"

#include <stdio.h>
#include <string.h>

#include "esp_log.h"

static const char *TAG = "app_nvs";

int app_nvs_get_wifi_sta_info(app_wifi_info_t *wifi_info)
{
    app_sta_conn_info_t wifi_sta_info = {0};

    if (hal_nvs_get_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_WIFI_STA_INFO, &wifi_sta_info, sizeof(wifi_sta_info)) != 0)
    {
        ESP_LOGW(TAG, "Failed to get wifi sta info");
        return -1;
    }

    strcpy(wifi_info->conn_info.ssid, wifi_sta_info.ssid);
    strcpy(wifi_info->conn_info.pwd, wifi_sta_info.pwd);

    return 0;
}

int app_nvs_save_wifi_sta_info(app_wifi_info_t *wifi_info)
{
    if (hal_nvs_set_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_WIFI_STA_INFO, &wifi_info->conn_info, sizeof(wifi_info->conn_info)) != 0)
    {
        ESP_LOGE(TAG, "Failed to save wifi sta info");
        return -1;
    }

    return 0;
}

int app_nvs_get_wifi_mode(hal_wifi_mode_t *mode)
{
    hal_wifi_mode_t mode_tmp;
    if (hal_nvs_get_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_WIFI_MODE, &mode_tmp, sizeof(mode_tmp)) != 0)
    {
        ESP_LOGW(TAG, "Failed to get wifi mode");
        return -1;
    }

    *mode = mode_tmp;

    return 0;
}

int app_nvs_save_wifi_mode(hal_wifi_mode_t mode)
{
    if (hal_nvs_set_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_WIFI_MODE, &mode, sizeof(hal_wifi_mode_t)) != 0)
    {
        ESP_LOGE(TAG, "Failed to save wifi mode");
        return -1;
    }

    return 0;
}

int app_nvs_get_mqtt_cfg(app_mqtt_cfg_t *mqtt_cfg)
{
    app_mqtt_cfg_t mqtt_cfg_tmp = {0};

    if (hal_nvs_get_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_MQTT_CFG, &mqtt_cfg_tmp, sizeof(mqtt_cfg_tmp)) != 0)
    {
        ESP_LOGW(TAG, "Failed to get mqtt cfg");
        return -1;
    }

    memcpy(mqtt_cfg, &mqtt_cfg_tmp, sizeof(app_mqtt_cfg_t));

    return 0;
}

int app_nvs_save_mqtt_cfg(app_mqtt_cfg_t *mqtt_cfg)
{
    if (hal_nvs_set_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_MQTT_CFG, mqtt_cfg, sizeof(app_mqtt_cfg_t)) != 0)
    {
        ESP_LOGE(TAG, "Failed to save mqtt cfg");
        return -1;
    }

    return 0;
}

int app_nvs_get_mqtt_topic(app_mqtt_topic_t *mqtt_topic)
{
    app_mqtt_topic_t mqtt_topic_tmp = {0};

    if (hal_nvs_get_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_MQTT_TOPIC, &mqtt_topic_tmp, sizeof(app_mqtt_topic_t)) != 0)
    {
        ESP_LOGW(TAG, "Failed to get mqtt topic");
        return -1;
    }

    memcpy(mqtt_topic, &mqtt_topic_tmp, sizeof(app_mqtt_topic_t));

    return 0;
}

int app_nvs_save_mqtt_topic(app_mqtt_topic_t *mqtt_topic)
{
    if (hal_nvs_set_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_MQTT_TOPIC, mqtt_topic, sizeof(app_mqtt_topic_t)) != 0)
    {
        ESP_LOGE(TAG, "Failed to save mqtt topic");
        return -1;
    }

    return 0;
}

int app_nvs_get_ota_cfg(app_ota_config_t *ota_cfg)
{
    app_ota_config_t ota_cfg_tmp = {0};

    if (hal_nvs_get_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_OTA_CFG, &ota_cfg_tmp, sizeof(app_ota_config_t)) != 0)
    {
        ESP_LOGW(TAG, "Failed to get ota cfg");
        return -1;
    }

    memcpy(ota_cfg, &ota_cfg_tmp, sizeof(app_ota_config_t));

    return 0;
}

int app_nvs_save_ota_cfg(app_ota_config_t *ota_cfg)
{
    if (hal_nvs_set_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_OTA_CFG, ota_cfg, sizeof(app_ota_config_t)) != 0)
    {
        ESP_LOGE(TAG, "Failed to save ota cfg");
        return -1;
    }

    return 0;
}

int app_nvs_get_ota_server_cfg(app_ota_server_config_t *ota_server_cfg)
{
    app_ota_server_config_t ota_server_cfg_tmp = {0};

    if (hal_nvs_get_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_OTA_SERVER_CFG, &ota_server_cfg_tmp, sizeof(app_ota_server_config_t)) != 0)
    {
        ESP_LOGW(TAG, "Failed to get ota server cfg");
        return -1;
    }

    memcpy(ota_server_cfg, &ota_server_cfg_tmp, sizeof(app_ota_server_config_t));

    return 0;
}

int app_nvs_save_ota_server_cfg(app_ota_server_config_t *ota_server_cfg)
{
    if (hal_nvs_set_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_OTA_SERVER_CFG, ota_server_cfg, sizeof(app_ota_server_config_t)) != 0)
    {
        ESP_LOGE(TAG, "Failed to save ota server cfg");
        return -1;
    }

    return 0;
}

int app_nvs_get_device_state(app_iot_device_state_t *device_state)
{
    app_iot_device_state_t device_state_tmp = {0};

    if (hal_nvs_get_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_DEVICE_STATE, &device_state_tmp, sizeof(app_iot_device_state_t)) != 0)
    {
        ESP_LOGW(TAG, "Failed to get device state");
        return -1;
    }

    memcpy(device_state, &device_state_tmp, sizeof(app_iot_device_state_t));

    return 0;
}

int app_nvs_save_device_state(app_iot_device_state_t *device_state)
{
    if (hal_nvs_set_blob(APP_NVS_NAMESPACE, APP_NVS_KEY_DEVICE_STATE, device_state, sizeof(app_iot_device_state_t)) != 0)
    {
        ESP_LOGE(TAG, "Failed to save device state");
        return -1;
    }

    return 0;
}

int app_nvs_load_all_cfg(void)
{
    app_wifi_info_t *wifi_info = app_wifi_get_info();
    if (app_nvs_get_wifi_sta_info(wifi_info) != 0)
    {
        wifi_info->mode = HAL_WIFI_MODE_AP;
    }
    else
    {
        ESP_LOGI(TAG, "ssid:%s", wifi_info->conn_info.ssid);
        ESP_LOGI(TAG, "pwd:%s", wifi_info->conn_info.pwd);
        wifi_info->mode = HAL_WIFI_MODE_STA;
    }
    app_nvs_get_wifi_mode(&wifi_info->mode);
    // wifi_info->mode = HAL_WIFI_MODE_STA;
    // strcpy(wifi_info->conn_info.ssid, "aiot");
    // strcpy(wifi_info->conn_info.pwd, "aiot@888");

    app_mqtt_info_t *mqtt_info = app_mqtt_get_info();
    app_nvs_get_mqtt_cfg(&mqtt_info->cfg);
    app_nvs_get_mqtt_topic(&mqtt_info->topic);

    app_ota_config_t *ota_cfg = app_ota_get_cfg();
    app_nvs_get_ota_cfg(ota_cfg);

    app_ota_server_config_t *ota_server_cfg = app_ota_get_server_cfg();
    app_nvs_get_ota_server_cfg(ota_server_cfg);

    app_iot_device_state_t *device_state = app_iot_ctrl_get_device_state();
    app_nvs_get_device_state(device_state);

    return 0;
}

int app_nvs_restore_factory(void)
{
    hal_nvs_erase_key(APP_NVS_NAMESPACE, APP_NVS_KEY_WIFI_STA_INFO);
    hal_nvs_erase_key(APP_NVS_NAMESPACE, APP_NVS_KEY_WIFI_MODE);
    hal_nvs_erase_key(APP_NVS_NAMESPACE, APP_NVS_KEY_MQTT_CFG);
    hal_nvs_erase_key(APP_NVS_NAMESPACE, APP_NVS_KEY_MQTT_TOPIC);
    hal_nvs_erase_key(APP_NVS_NAMESPACE, APP_NVS_KEY_OTA_CFG);
    hal_nvs_erase_key(APP_NVS_NAMESPACE, APP_NVS_KEY_OTA_SERVER_CFG);
    hal_nvs_erase_key(APP_NVS_NAMESPACE, APP_NVS_KEY_DEVICE_STATE);

    return 0;
}
